library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ImageController is
  Port(IMG_Data : in std_logic_vector(9 downto 0);
			IMG_PIXEL_Clk : in std_logic;
			IMG_ROW_EN : in std_logic;
			
			OEM_Data : out std_logic_vector(9 downto 0);
			OEM_PIXEL_Clk : out std_logic;
			OEM_ROW_EN : out std_logic;
			OEM_VSYNC : out std_logic;
			
			Row : out std_logic_vector(8 downto 0);
			Col : out std_logic_vector(9 downto 0));
end ImageController;

architecture beh of ImageController is

  component EdgeDetector is
    port (Sig : in std_logic;
          Clk : in std_logic;
          FallingEdge : out std_logic;
          RisingEdge : out std_logic);
  end component;

  signal pclk,row_en : std_logic:='0';
  signal dat : std_logic_vector(9 downto 0):="0000000000";
  
  signal vsync,hsync : std_logic;
  
  signal rowCount : std_logic_vector(8 downto 0):=(others=>'0');
  signal colCount : std_logic_vector(9 downto 0):=(others=>'0');
  
  signal count: std_logic_vector(15 downto 0):=X"0000";
  
  signal hsize : natural:=752;
  signal vsize : natural:=480;
  
  signal vblank : natural:=45;
  signal hblank : natural:=94;
  
  type states is (calibrate,frameStart);
  signal cs : states:=calibrate;

begin
			
	OEM_PIXEL_Clk <=IMG_PIXEL_Clk;
	OEM_ROW_EN <=hsync;
	OEM_VSYNC <=vsync;
	OEM_Data<=dat;
	
	dat<=IMG_Data;
  
  pclk<=IMG_PIXEL_Clk;
  row_en<=IMG_ROW_EN;
  
  Row<=rowCount;
  Col<=colCount;
  
  process(pclk,cs,row_en,count)
  begin
	 if rising_edge(pclk) then
		 case cs is
			when calibrate => 
			  if row_en = '1' and count > 1000 then
				 cs <= frameStart;
			  end if;
			when frameStart => null;
			when others =>
		 end case;
	 end if;
  end process;
  
  ------------------------
  --State Machine Datapath
  ------------------------    
  process(pclk,cs,row_en,dat)
  begin
    if rising_edge(pclk) then
      case cs is
        when calibrate =>
          if (row_en = '0') then
            count <= count+1;
          else
            count<=(others=>'0');
          end if;
          rowCount<=(others=>'0');
          colCount<=(others=>'0');
        when frameStart =>
          colCount<=colCount + 1;
          if colCount = hsize then
            colCount<=(others=>'0');
            if rowCount = vsize-1 then
              rowCount<=(others=>'0');
            else
              rowCount<=rowCount+1;
            end if;
          end if;          
        when others =>
          null;
      end case;
    end if;
  end process;
  
  --Outputs
  process (rowCount,colCount,cs)
  begin
    if cs = frameStart then
      if colCount > hsize - hblank - 1 then
        hsync <='0';
      else
        hsync<='1';
      end if;
      
      if rowCount < vsize - vblank - 1 then
        vsync <= '1';
      elsif rowCount = vsize-1 and colCount >= hsize - hblank + 23 then
        vsync <= '1';
      else
        vsync <= '0';
        hsync<='0';
      end if;
    else
      hsync<='0';
      vsync<='0';
    end if;
  end process;
    
  
end beh;